With Play App Signing the store build asserts WebAuthn ceremonies with
Google's app-signing cert, while locally-signed release builds assert
with the upload cert. expectedOrigins only accepted one
ANDROID_RELEASE_HASH, so upload-signed builds always failed
verification ("Verification failed" in the Android app).
ANDROID_RELEASE_HASH now accepts a comma-separated list (whitespace
tolerated, empty segments dropped); existing single-value envs behave
unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNhXd8EkXcrjBVYLHm5ZSp
Why
With Play App Signing, the Play-delivered app asserts WebAuthn ceremonies with Google's app-signing certificate, while a locally-built release APK is signed with the upload key.
PasskeyService.expectedOriginsaccepted only oneANDROID_RELEASE_HASH, so passkey sign-in from an upload-signed build always failed server-side ("Verification failed" in the app) — found while smoke-testing the Android R8 build (bookplayer-android#80).What
ANDROID_RELEASE_HASHnow accepts a comma-separated list ofandroid:apk-key-hash:origins (whitespace tolerated, empty segments dropped). Existing single-value envs behave identically.development.env.templatedocuments the list form.Deploy note
After merge, append the upload-key origin to the prod
ANDROID_RELEASE_HASH(comma-separated, after the existing Play-signing value):(SHA-256 of the upload certificate — same fingerprint already listed in bookplayer.github.io's assetlinks.json, so the client-side gate already passes.)
No DB changes, no migrations.
🤖 Generated with Claude Code
https://claude.ai/code/session_01YNhXd8EkXcrjBVYLHm5ZSp